#include "ParallelLight.cuh"

using namespace OBR;

__forceinline__ __device__ Spectrum calcLi(SamplePRD *prd, float *pdf, ParallelLightData *data)
{
    *pdf = 0.0f;
    return Spectrum(0.0f);
}

__forceinline__ __device__ Spectrum sampleLi(SamplePRD *prd, float *pdf, float u0, float u1,
                                             ParallelLightData *data)
{
    *pdf = 1.0f;
    prd->inter.wi = prd->inter.spawnRay(-data->direction);
    return data->radiance;
}

extern "C" __device__ Spectrum __direct_callable__parallel_light(SamplePRD *prd, float *pdf,
                                                                 int instance_id, float u0,
                                                                 float u1,

                                                                 LightCallMode mode)
{
#ifdef DEBUG_SHADER
    if (prd->log)
    {
        printf("==== parallel light program launched\n");
    }
#endif

    CallableData *sbt_record = reinterpret_cast<CallableData *>(optixGetSbtDataPointer());

    if (instance_id < sbt_record->n_instances)
    {
        ParallelLightData *data =
            reinterpret_cast<ParallelLightData *>(sbt_record->callable_payload) + instance_id;
        if (mode == LightCallMode::SAMPLE_LI)
        {
            return sampleLi(prd, pdf, u0, u1, data);
        }
        else if (mode == LightCallMode::CALC_LI_PDF)
        {
            return calcLi(prd, pdf, data);
        }
    }
    return Spectrum(0.0f);
}